/**
 * Copyright 2015 ABSir's Studio
 * 
 * All right reserved
 *
 * Create on 2015年10月5日 上午10:51:46
 */
package com.absir.appserv.system.asset;

import java.io.IOException;
import java.net.URLDecoder;
import java.util.Map;

import com.absir.appserv.system.bean.JPayTrade;
import com.absir.appserv.system.bean.value.JePayStatus;
import com.absir.appserv.system.helper.HelperJson;
import com.absir.appserv.system.service.BeanService;
import com.absir.appserv.system.service.HuaweiService;
import com.absir.appserv.system.service.utils.PayUtils;
import com.absir.server.in.Input;
import com.absir.server.value.Body;
import com.absir.server.value.Nullable;
import com.absir.server.value.Param;
import com.absir.server.value.Server;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.huawei.pay.callback.util.CommonUtil;

/**
 * @author absir
 *
 */
@Server
public class Asset_huawei extends AssetServer {

	/**
	 * @param input
	 * @return
	 */
	@Body
	public String valid(Input input) {
		return "success";
	}

	/**
	 * @return
	 */
	@Body
	public String getPayPrivateKey() {
		return HuaweiService.HUAWEI_CONFIGURE.getPayPrivateKey();
	}

	/**
	 * @return
	 */
	@Body
	public String getIconPrivateKey() {
		return HuaweiService.HUAWEI_CONFIGURE.getIconPrivateKey();

	}

	/**
	 * @param data
	 * @param input
	 * @return
	 * @throws JsonProcessingException
	 * @throws IOException
	 */
	@Body
	public String notify(@Nullable @Param String sign, @Nullable @Param Integer amount, @Nullable @Param Integer result,
			@Nullable @Param String errMsg, @Nullable @Param String requestId, Input input) throws IOException {
		if (HuaweiService.HUAWEI_CONFIGURE.isTest()) {
			return "{\"result\":0}";
		}

		if (sign == null || amount == null || result == null || requestId == null) {
			return "{\"result\":1}";
		}

		// 验签成功
		if (CommonUtil.rsaDoCheck(getValue(input), sign, HuaweiService.HUAWEI_CONFIGURE.getMerchantPublicKey())) {
			JPayTrade payTrade = BeanService.ME.get(JPayTrade.class, requestId);
			if (payTrade != null && result == 0) {
				payTrade.setPlatform(HuaweiService.PLAT_FORM_NAME);
				payTrade.setStatus(errMsg == null || errMsg.equals("success") && amount >= payTrade.getAmount() ? JePayStatus.PAYED
						: JePayStatus.ERROR);
				payTrade.setStatusData(errMsg);
				if (payTrade.getStatus() == JePayStatus.PAYED) {
					PayUtils.proccessDone(payTrade);

				} else {
					BeanService.ME.merge(payTrade);
				}
			}

		} else { // 验签失败
			return "{\"result\":1}";
		}

		// 构造返回值，如："{\"result\":0}"
		return "{\"result\":0}";
	}

	/**
	 * @param request
	 * @return 本接口Content-Type是：application/x-www-form-urlencoded，对所有参数，会自动进行编码，
	 *         接收端收到消息也会自动根据Content-Type进行解码。 同时，接口中参数在发送端并没有进行单独的URLEncode
	 *         (sign和extReserved
	 *         、sysReserved参数除外)，所以，在接收端根据Content-Type解码后，即为原始的参数信息。
	 *         但是HttpServletRequest的getParameter
	 *         ()方法会对指定参数执行隐含的URLDecoder.decode(),所以，相应参数中如果包含比如"%"，就会发生错误。
	 *         因此，我们建议通过如下方法获取原始参数信息。
	 * 
	 *         注：使用如下方法必须在原始ServletRequest未被处理的情况下进行，否则无法获取到信息。比如，在Struts情况，
	 *         由于struts层已经对参数进行若干处理，
	 *         http中InputStream中其实已经没有信息，因此，本方法不适用。要获取原始信息，
	 *         必须在原始的，未经处理的ServletRequest中进行。
	 */
	@SuppressWarnings("unchecked")
	protected Map<String, Object> getValue(Input input) {
		Map<String, Object> valueMap = (Map<String, Object>) (Object) HelperJson.buildParams(input.getParamMap());
		if (valueMap.isEmpty()) {
			return valueMap;
		}

		// 接口中，如下参数sign和extReserved、sysReserved是URLEncode的，所以需要decode，其他参数直接是原始信息发送，不需要decode
		try {
			String sign = (String) valueMap.get("sign");
			String extReserved = (String) valueMap.get("extReserved");
			String sysReserved = (String) valueMap.get("sysReserved");

			if (null != sign) {
				sign = URLDecoder.decode(sign, "utf-8");
				valueMap.put("sign", sign);
			}
			if (null != extReserved) {
				extReserved = URLDecoder.decode(extReserved, "utf-8");
				valueMap.put("extReserved", extReserved);
			}

			if (null != sysReserved) {
				sysReserved = URLDecoder.decode(sysReserved, "utf-8");
				valueMap.put("sysReserved", sysReserved);
			}

		} catch (Exception e) {
			e.printStackTrace();
		}

		return valueMap;

	}
}
